package com.yunchao.feature.business.presentation.screen.details

import android.os.Bundle
import android.text.InputType
import android.view.View
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import by.kirich1409.viewbindingdelegate.viewBinding
import com.chad.library.adapter4.BaseQuickAdapter
import com.xuexiang.xui.utils.WidgetUtils
import com.yunchao.feature.base.presentation.activity.BaseKeyEventFragment
import com.yunchao.feature.base.presentation.ext.hideLoadingDialog
import com.yunchao.feature.base.presentation.ext.setDebouncedClickListener
import com.yunchao.feature.base.presentation.ext.showConfirmDialog
import com.yunchao.feature.base.presentation.ext.showInputDialog
import com.yunchao.feature.base.presentation.ext.showLoadingDialog
import com.yunchao.feature.base.presentation.ext.showTipDialog
import com.yunchao.feature.base.presentation.ext.toast
import com.yunchao.feature.business.R
import com.yunchao.feature.business.databinding.FragmentBusinessDetailsBinding
import com.yunchao.feature.business.domain.enum.BusinessType
import com.yunchao.feature.business.domain.model.BusinessInfoModel
import com.yunchao.feature.business.domain.model.BusinessPackModel
import com.yunchao.feature.business.domain.model.getPackInfoMap
import com.yunchao.library.lock.lockIdToLockEPCInfo
import kotlinx.coroutines.launch
import org.koin.androidx.navigation.koinNavGraphViewModel
import java.math.BigDecimal
import java.util.concurrent.ConcurrentHashMap
import kotlin.getValue

internal class BusinessDetailsFragment : BaseKeyEventFragment(R.layout.fragment_business_details) {

    private val binding: FragmentBusinessDetailsBinding by viewBinding<FragmentBusinessDetailsBinding>()
    private val viewModel: BusinessDetailsViewModel by koinNavGraphViewModel(R.id.businessNavGraph)
    private val businessDetailsAdapter: BusinessDetailsAdapter by lazy { BusinessDetailsAdapter() }
    private val args: BusinessDetailsFragmentArgs by navArgs()

    private var packInfoMap: ConcurrentHashMap<String, BusinessPackModel> = ConcurrentHashMap()
    private var businessModel: BusinessInfoModel? = null
    private var isLoop: Boolean = false

    override fun initView(view: View, savedInstanceState: Bundle?) {
        viewModel.loadBusinessInfo(args)
        binding.lockHandleRV.apply {
            adapter = businessDetailsAdapter; WidgetUtils.initRecyclerView(this)
        }

        binding.superSwitchTV.setSwitchCheckedChangeListener { _, isChecked ->
            isLoop = isChecked; viewModel.setupPower(isChecked)
        }

        businessDetailsAdapter.addOnItemChildClickListener(R.id.lockCommonClose) { adapter, _, position ->
            deletePackInfo(adapter, position)
        }

        binding.submitBtn.setDebouncedClickListener { submitTaskOperation() }
        binding.submitButton.setDebouncedClickListener { submitTaskOperation() }
        binding.entryButton.setDebouncedClickListener { entryLockOperation() }


        lifecycleScope.launch { viewModel.uiStateFlow.collect(::render) }
        lifecycleScope.launch { viewModel.uiEffectFlow.collect(::sideEffect) }
    }

    private fun render(state: BusinessDetailsViewModel.UiState) {
        when (state) {
            is BusinessDetailsViewModel.UiState.Idle -> Unit
            is BusinessDetailsViewModel.UiState.Success -> handleTaskResult(state.businessInfoModel)

            is BusinessDetailsViewModel.UiState.GetPackInfo -> handleScanResult(
                packInfoList = state.packInfoList,
                packInfo = state.packInfo
            )

        }
    }

    private fun sideEffect(effect: BusinessDetailsViewModel.UiEffect) {
        when (effect) {
            is BusinessDetailsViewModel.UiEffect.ShowToast -> toast(effect.msg)

            is BusinessDetailsViewModel.UiEffect.ShowLoading -> showLoadingDialog()

            is BusinessDetailsViewModel.UiEffect.HideLoading -> hideLoadingDialog()

            is BusinessDetailsViewModel.UiEffect.SubmitSuccess -> showTipDialog(
                icon = com.yunchao.feature.base.R.drawable.ic_success_img,
                title = getString(com.yunchao.feature.base.R.string.提示),
                content = effect.msg
            ) {
                findNavController().navigateUp()
            }
        }
    }


    /**
     * 当前要处理的任务
     */
    private fun handleTaskResult(businessModel: BusinessInfoModel) {
        this.businessModel = businessModel
        val tranTypeId = businessModel.tranTypeID
        // 更新列表与包信息
        businessDetailsAdapter.submitList(businessModel.packInfoPayloads.toMutableList())
        packInfoMap = ConcurrentHashMap(businessModel.getPackInfoMap())

        // 使用 when 简化业务类型判断
        val isType003Or001 = tranTypeId in listOf(
            BusinessType.BusinessTypeMIMISIF003.type,
            BusinessType.BusinessTypeMIMISIF001.type
        )
        val isType003Or005 = tranTypeId in listOf(
            BusinessType.BusinessTypeMIMISIF003.type,
            BusinessType.BusinessTypeMIMISIF005.type
        )

        binding.apply {
            // 根据业务类型设置视图的可见性
            submitBtn.visibility = if (isType003Or001) View.VISIBLE else View.GONE
            businessBtnLayout.visibility = if (isType003Or001) View.GONE else View.VISIBLE
            scanTotalCount.visibility = if (isType003Or005) View.VISIBLE else View.GONE
            superSwitchTV.visibility = if (isType003Or005) View.GONE else View.VISIBLE

            // 显示任务编号
            taskTranId.text = getString(
                com.yunchao.feature.base.R.string.业务编号,
                businessModel.tranID
            )

            // 更新 UI
            updateUIForBusiness(isType003Or005)
        }
    }


    /**
     * 处理扫描结果
     */
    private fun handleScanResult(
        packInfo: BusinessPackModel? = null,
        packInfoList: List<BusinessPackModel> = emptyList()
    ) {

        // 处理单个PackInfo
        fun processPackInfo(packInfo: BusinessPackModel) {
            packInfo.lockEPCInfo?.id?.let { lockId ->
                when (businessModel?.tranTypeID) {
                    BusinessType.BusinessTypeMIMISIF001.type -> packInfoMap[lockId] = packInfo
                    else -> packInfoMap.remove(lockId)
                }
            }
        }

        packInfo?.let {
            if (BusinessType.BusinessTypeMIMISIF003.type == businessModel?.tranTypeID && !it.handleResult) {
                businessModel?.let { info ->
                    showCloseLockDialog(
                        context = requireActivity(),
                        busiInfoList = info.busiInfoList.ifEmpty { info.packInfoList },
                        packInfoModel = it
                    ) { pageNumber, busiInfo, _ ->
                        viewModel.closeLock(
                            packInfo = it,
                            business = info,
                            busiInfo = busiInfo,
                            pageNumber = pageNumber
                        )
                    }
                }
            } else {
                processPackInfo(it).apply {
                    businessDetailsAdapter.add(0, it)
                }
            }
        } ?: run {
            // 处理packInfoList
            packInfoList.forEach { processPackInfo(it) }.apply {
                businessDetailsAdapter.addAll(0, packInfoList)
            }
        }

        // 滚动到顶部并更新UI
        binding.lockHandleRV.smoothScrollToPosition(0)
        updateUIForBusiness()
    }



    private fun updateUIForBusiness(isType003Or005: Boolean? = null) {
        // 如果 Switch 没有开启，则处理业务逻辑
        businessModel?.takeIf { !isLoop }?.let {
            viewModel.updateBusiness(it, businessDetailsAdapter.items, isLoop)
        }

        // 简化 authResult 的计算
        val authResult = isType003Or005 ?: listOf(
            BusinessType.BusinessTypeMIMISIF003.type,
            BusinessType.BusinessTypeMIMISIF005.type
        ).contains(businessModel?.tranTypeID)

        // 懒加载计算总金额，只有在 authResult 为 true 时才会计算
        val totalAmount by lazy {
            businessDetailsAdapter.items
                .filter { it.sackMoney.isNotBlank() }
                .sumOf { BigDecimal(it.sackMoney) }
        }

        // 更新 UI
        binding.apply {
            val totalCountString = getString(
                com.yunchao.feature.base.R.string.扫描总数,
                businessDetailsAdapter.itemCount
            )
            val totalAmountString = getString(
                com.yunchao.feature.base.R.string.扫描总金额,
                if (authResult) totalAmount.toPlainString() else "0"
            )
            // 一次性更新 UI
            superSwitchTV.setLeftString(totalCountString)
            scanTotalCount.setLeftString(totalCountString)
                .setRightString(totalAmountString)
        }
    }

    /**
     * 提交任务
     */
    private fun submitTaskOperation() {
        if (businessDetailsAdapter.items.isEmpty()) {
            toast(com.yunchao.feature.base.R.string.暂无待提交的数据)
            return
        }
        businessModel?.apply {
            viewModel.submitBusiness(this, businessDetailsAdapter.items)
        }

    }


    /**
     * 手动录入
     */
    private fun entryLockOperation() {
        requireActivity().showInputDialog(
            title = getString(com.yunchao.feature.base.R.string.提示),
            content = getString(com.yunchao.feature.base.R.string.手动录入锁号),
            defaultContent = getString(com.yunchao.feature.base.R.string.输入锁号),
            inputType = InputType.TYPE_CLASS_NUMBER
        ) { content ->
            when {
                content.isNullOrBlank() -> {
                    toast(com.yunchao.feature.base.R.string.请输入锁号)
                }

                businessDetailsAdapter.items.any { it.sackNo == content } -> {
                    toast(com.yunchao.feature.base.R.string.当前锁已扫描过)
                }

                else -> {
                    packInfoMap.remove(content)?.let {
                        // 锁号存在 packInfoMap 中，执行相关操作
                        handleScanResult(
                            it.copy(
                                lockEPCInfo = lockIdToLockEPCInfo(
                                    content,
                                    it.value,
                                    BusinessType.BusinessTypeMIMISIF003.type == businessModel?.tranTypeID
                                ),
                                handleResult = true
                            )
                        )
                    } ?: run {
                        toast(com.yunchao.feature.base.R.string.锁号不匹配STR)
                    }
                }
            }
        }
    }




    private fun deletePackInfo(adapter: BaseQuickAdapter<BusinessPackModel, *>, position: Int) {
        adapter.getItem(position)?.apply {
        showConfirmDialog(
                content =  getString(
                    com.yunchao.feature.base.R.string.是否确定删除锁号为的包装袋,
                    lockEPCInfo?.id
                )
            ){
                if (businessModel?.tranTypeID == BusinessType.BusinessTypeMIMISIF001.type) {
                    packInfoMap.remove(lockEPCInfo?.id)
                } else {
                    lockEPCInfo?.id?.let { packInfoMap.put(it, this) }
                }.apply {
                    adapter.removeAt(position)
                    updateUIForBusiness()
                }
            }
        }
    }

    override fun onceScanLock() {
        super.onceScanLock()
        businessModel?.let { business ->
            when {
                //开锁
                business.tranTypeID == BusinessType.BusinessTypeMIMISIF005.type -> viewModel.openLock(
                    packInfoMap = packInfoMap,
                    business = business
                )

                //群扫
                isLoop -> viewModel.inventoryLoop(business, packInfoMap)

                //单扫
                else -> viewModel.inventoryOnce(business, packInfoMap)
            }
        }
    }

    override fun onStopScanLock() {
        super.onStopScanLock()
        if (isLoop) {
            businessModel?.apply {
                viewModel.updateBusiness(this, businessDetailsAdapter.items, true)
            }
        }
    }
}